package com.foreveross.fetl.queue;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import javax.inject.Inject;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;

import com.foreveross.fetl.application.IOfficChannelSpreadApplication;
import com.foreveross.fetl.application.ISinglePlaneInfoApplication;
import com.foreveross.fetl.core.domain.task.FlightInfoEntity;
import com.foreveross.fetl.core.domain.task.SourceEntity;
import com.foreveross.fetl.core.domain.task.UserCareLineEntity;
import com.foreveross.fetl.queue.util.LogMessageUtils;
import com.foreveross.fetl.util.DateUtils;
import com.foreveross.fetl.vo.OfficChannelSpreadVO;
import com.foreveross.fetl.vo.OfficalChannelPlusTop5;
import com.foreveross.fetl.vo.single.SinglePlaneInfoVO;


/*-
 每天的官网和渠道的航班的价差的 top5

 循环所有的航空公司
 循环某航空公司某航线下
 循环所有的航班
 循环查询未来30天的航空公司官网的价格
 最新的航班最低价（即以最新一次取到的数据为准）[官网、渠道]航班最低价LP_FLIGHT 
 rowkey： 航班时间(年月日)_官网_渠道_起点_终点_航班号
 循环查询渠道【淘宝、去哪网】上的此航班的价格
 求此航线的top5

 将统计结果保存到hbase中  LP_FLIGHT_PULS

 * @author tss
 *
 */
@Component
public class FlightOfficialAndChannelPulsTop5 {

	private Logger log = Logger.getLogger(FlightOfficialAndChannelPulsTop5.class);
	
	
	@Inject
	private IOfficChannelSpreadApplication officChannelSpreadApplication;
	
	@Inject
	private ISinglePlaneInfoApplication singlePlaneInfoApplication;
	
	private int tasksNumber;//任务数 多少条rowkey
	
	private int failuresNumber;//失败数

	
	private int insertNumber; //插入条数 
	
	private long startTime;
	
	
	private String taskTime=null;
	
	public void  rollBackNumber(){
		tasksNumber=0;
		failuresNumber=0;
		insertNumber=0;
		startTime = System.currentTimeMillis();
		LogMessageUtils.create("官网和渠道差价的前五名", this.getClass().getSimpleName());

	}
	
	/**
	 * @param args
	 */
	public void execute() {
		long start = System.currentTimeMillis();
		log.info("top5 count start:"
				+ DateUtils.format(new Date(), "yyyy-MM-dd hh:mm:ss.SSS"));
		rollBackNumber();
		try {
			processOfficalChannelPlus(new Date());
		} catch (Exception e) {
			LogMessageUtils.build("官网和渠道差价的前五名", this.getClass().getSimpleName(), 3, 
					com.foreveross.fetl.util.StringUtils.getStackTrace(e), failuresNumber, tasksNumber, 
					insertNumber, taskTime, startTime);
			e.printStackTrace();
		}
		log.info("top5 count end："
				+ DateUtils.format(new Date(), "yyyy-MM-dd hh:mm:ss.SSS") +" spend time:"+(System.currentTimeMillis() - start));
	}
	/**
	 * 从已知的航空公司航班集合中取出某条航线的航班
	 * @param allFlights
	 * @param fromCode
	 * @param toCode
	 * @return
	 */
	private List<FlightInfoEntity> getFlightNoByLine(List<FlightInfoEntity> allFlights,
			String fromCode, String toCode){
		List<FlightInfoEntity> tempFlights = new ArrayList<FlightInfoEntity>();
		if(allFlights != null && StringUtils.isNotBlank(fromCode) && StringUtils.isNotBlank(toCode)){
			for(FlightInfoEntity e : allFlights){
				if(fromCode.equalsIgnoreCase(e.getFromCity())
						&& toCode.equalsIgnoreCase(e.getToCity())){
					tempFlights.add(e);
				}
			}
		}
		return tempFlights;
	}
	public void processOfficalChannelPlus(Date date) {
		
		
		Calendar c = null;
		
	//	TaskTemplateEntity task = new TaskTemplateEntity();
		SourceEntity source = new SourceEntity();
	//	List<TaskTemplateEntity> lines = null;
		UserCareLineEntity userCareLineEntity =new UserCareLineEntity();
		List<UserCareLineEntity> lines =userCareLineEntity.findUserCareLines();
		log.info("top5 Get channels");
		//渠道
		Collection<SourceEntity> channels = source.findSourceEntityByType(SourceEntity.TYPE_CHNNAEL);
		//官网
		Collection<SourceEntity> homes = source.findSourceEntityByType(SourceEntity.TYPE_HOME);
		
		for (SourceEntity home : homes) {
			c = Calendar.getInstance();// 统计的当天
			c.setTime(date);
			int maxCountDays = c.getActualMaximum(Calendar.DAY_OF_MONTH);
			for (int i = 0; i < maxCountDays; i++) {
				for (UserCareLineEntity line : lines) {
					String fromCity =line.getDepartCityCode();
					String tocity=line.getArrivalCityCode();
					List<OfficalChannelPlusTop5> officalChannelPlusTop5s = new ArrayList<OfficalChannelPlusTop5>();
					List<SinglePlaneInfoVO> listPlaneInfo=singlePlaneInfoApplication.findPlaneInfoProperty(home.getHbaseKey(),null, fromCity, tocity, DateUtils.format(c.getTime(), "yyyy-MM-dd"), null,null);
					for (SinglePlaneInfoVO planeInfo : listPlaneInfo) {
						try {
							tasksNumber++;
							if(null==planeInfo.getFlightNo()){
								continue;
							}
							for (SourceEntity channel : channels) {
								OfficalChannelPlusTop5 officalChannel = new OfficalChannelPlusTop5();
								officalChannel.setHomePlaneInfo(planeInfo);
								List<SinglePlaneInfoVO>	channelPlaneInfo=singlePlaneInfoApplication.findPlaneInfoProperty(channel.getHbaseKey(),home.getCarrierKey(), fromCity, tocity, DateUtils.format(c.getTime(), "yyyy-MM-dd"), planeInfo
										.getFlightNo(),null);
								if(null==channelPlaneInfo || channelPlaneInfo.isEmpty()){
									continue;
								}
								officalChannel.setChannelPlaneInfo(channelPlaneInfo.get(0));
									
								officalChannelPlusTop5s.add(officalChannel);
							}
						} catch (Exception e) {
							failuresNumber++;
							log.error(e.getMessage());
							continue;
						}
					}
					// 保存统计结果
					Collections.sort(officalChannelPlusTop5s);
					int j = 0;
					log.info("top5 compare OfficalChannelPlus "+officalChannelPlusTop5s.size());
					List<OfficChannelSpreadVO> list =new ArrayList<OfficChannelSpreadVO>();
					for (OfficalChannelPlusTop5 top : officalChannelPlusTop5s) {
						j = j + 1;
						if (j > 10) {
							break;
						}
					//	log.info("top5 saveResultToHBase ");
					//	saveResultToHBase(top, c.getTime());
						OfficChannelSpreadVO vo =this.resultToVO(top, date);
						list.add(vo);
						
					}
					if(null!=list && !list.isEmpty()){
						log.info(list.size());
						OfficChannelSpreadVO vo=list.get(0);
						List<OfficChannelSpreadVO> oldList =officChannelSpreadApplication.findByCondition(vo.getReportDate(), vo.getFlightDate(), vo.getFromCity(), vo.getToCity(), null, null, vo.getHbaseKey());
						officChannelSpreadApplication.removeList(oldList);
						officChannelSpreadApplication.saveList(list);
						insertNumber+=list.size();
					}
				}
				c.add(Calendar.DAY_OF_MONTH, 1);
			}
		}
		
		LogMessageUtils.build("官网和渠道差价的前五名", this.getClass().getSimpleName(), 2, null, 
				failuresNumber, tasksNumber, insertNumber, taskTime, startTime);
	}
	
	private OfficChannelSpreadVO resultToVO(OfficalChannelPlusTop5 top, Date date){
		SinglePlaneInfoVO homeInfo = top.getHomePlaneInfo();
		SinglePlaneInfoVO channelInfo = top.getChannelPlaneInfo();
		OfficChannelSpreadVO vo =new OfficChannelSpreadVO();
		vo.setReportDate(DateUtils.parse(DateUtils.format(date, "yyyyMMdd"),"yyyyMMdd"));
		vo.setChannelName(channelInfo.getGrabChannelName());
		vo.setHbaseName(homeInfo.getGrabChannelName());
		vo.setChannel(channelInfo.getAttachHbaseKey());
		vo.setChannelPrice(channelInfo.getTotalLowestPrice());
		vo.setFlightDate(DateUtils.parse(homeInfo.getFlightDate(),"yyyy-MM-dd"));
		vo.setFlightNo(homeInfo.getFlightNo());
		vo.setFromCity(homeInfo.getFromCity());
		vo.setFromCityName(homeInfo.getFromCityName());
		vo.setToCity(homeInfo.getToCity());
		vo.setToCityName(homeInfo.getToCityName());
		vo.setGrabTime(homeInfo.getCreateTime());
		vo.setHbaseKey(homeInfo.getAttachHbaseKey());
		vo.setHomePrice(homeInfo.getTotalLowestPrice());
		return vo;
	}

	/**
	 * 将统计结构保存到hbase中 LP_FLIGHT_OFFICIAL_CHANNEL_PLUS_TOP5 <br>
	 * rowkey: 航班日期_官网code_起点城市_终点城市
	 * 
	 * @param top
	 * @param c
	 */
/*	public void saveResultToHBase(OfficalChannelPlusTop5 top, Date date) {
		try {
			PlaneInfo homeInfo = top.getHomePlaneInfo();
			PlaneInfo channelInfo = top.getChannelPlaneInfo();
			StringBuffer topRowkey = new StringBuffer();
			topRowkey.append(DateUtils.format(date, "yyyyMMdd"));
			topRowkey.append(homeInfo.getGrabChannelNum());//官网
			//topRowkey.append(channelInfo.getGrabChannelNum());//渠道
			topRowkey.append(homeInfo.getFromCity());
			topRowkey.append(homeInfo.getToCity());
			topRowkey.append(RowkeyUtils.getFlightIdHbaseKey(homeInfo.getFlightId()));
			
			Put put = new Put(topRowkey.toString().getBytes());
			put.add("content".getBytes(), "flightBatch".getBytes(), channelInfo
					.getFlightId().getBytes());
			put.add("content".getBytes(), "flightBatchDate".getBytes(),
					channelInfo.getFlightBatchDate().getBytes());

			put.add("content".getBytes(), "grabChannelNum".getBytes(),
					channelInfo.getGrabChannelNum().getBytes());
			put.add("content".getBytes(), "grabChannel".getBytes(), channelInfo
					.getGrabChannel().getBytes());
			put.add("content".getBytes(), "agentName".getBytes(), channelInfo
					.getAgentName().getBytes());
			put.add("content".getBytes(), "grabDate".getBytes(), channelInfo
					.getGrabDate().getBytes());

			put.add("content".getBytes(), "homePrice".getBytes(), homeInfo
					.getLowerPrice().getBytes());
			put.add("content".getBytes(), "channelPrice".getBytes(),
					channelInfo.getLowerPrice().getBytes());
//			log.error("addRecord hbase key:"+homeInfo.getGrabChannelNum());
			HBaseHelper.addRecord(
					HBaseTable.TABLE_FLIGHT_OFFICIAL_CHANNEL_PLUS_TOP5, put);
			insertNumber++;
//			if (log.isDebugEnabled()) {
//				log.debug("TABLE_FLIGHT_OFFICIAL_CHANNEL_PLUS_TOP5  rowkey["
//						+ topRowkey.toString() + "]    channelRowkey["
//						+ top.getChannelRowkey() + "]" + "  homeRowkey["
//						+ top.getHomeRowkey() + "]");
//			}
		} catch (Exception e) {
			failuresNumber++;
			log.error("channelRowkey[" + top.getChannelRowkey() + "]"
					+ "  homeRowkey[" + top.getHomeRowkey() + "]");
			log.error(e.getMessage());
		}

	}*/
	


}
